package com.beiding.mpTimer;

import java.util.ArrayList;
import java.util.List;

/**
 * 任务执行者
 * <p>
 * 聚合任务处理器.当有任务需要被执行的时候会从任务处理器的集合中遍历,直到找到可以处理的处理器为止处理结束
 */

public abstract class Executor {

    private List<Handler> handlers = new ArrayList<>();

    /**
     * 添加一个任务处理器
     *
     * @param handler 处理器
     * @throws RepetitionHandlerException 重复添加某类型某主题的处理器
     */
    public void addHandler(Handler handler) {

        for (Handler h : handlers) {
            if (h.getType().equals(handler.getType()) && h.getTopic().equals(handler.getTopic())) {
                throw new RepetitionHandlerException();
            }
        }

        handlers.add(handler);

    }

    /**
     * 处理一个任务
     */
    public void handle(TaskPersistence persistence) {

        try {
            Class<?> type = persistence.getPayload().getClass();

            for (Handler handler : handlers) {

                //当类型和主题都匹配时才交给该处理器处理
                if (handler.getType().equals(type) && handler.getTopic().equals(persistence.getTopic())) {

                    handler.handle(persistence.getPayload(), persistence.getHappenTimeMillis());

                    onSuccess(persistence);

                    return;
                }
            }

            onNoSuchHandler(persistence);
        } catch (Exception e) {
            onException(persistence, e);
        }

    }

    //当任务处理成功时调用
    protected abstract void onSuccess(TaskPersistence persistence);

    //任务处理出现异常时调用.处理器处理是应该自行捕获并处理异常,该方法是处理器未处理异常时的默认处理
    protected abstract void onException(TaskPersistence persistence, Exception exception);

    //当没有这种类型的处理器时调用
    protected abstract void onNoSuchHandler(TaskPersistence persistence);

}
